/**
 * The dialog utility class of the Megatron Addin UI
 */
jsx3.lang.Class.defineClass("ux.megatron.Dialog", null, null, function(main) {

    /**
     * Show an alert dialog.  The signature and usage is identical to that in the standard GI alert function, but it gives
     * an alert dialog that uses the MatrixAdmin Visual Style.
     *
     * @param strTitle {String} the title of the dialog
     * @param strMessage {String} the message to display
     * @param fctOnOk {Function} callback function on pressing ok button, receives the dialog as an argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param strOk {String} the text of the ok button, can be false to remove button from display
     * @param objParams {objParams} argument to configureAlert()
     */
    main.alert = function(strTitle, strMessage, fctOnOk, strOk, objParams) {
        var dialog = ux.megatron.Main.getServer().getBodyBlock().loadAndCache('jsxaddin://user!Megatron/components/alertDialog.xml', false);
        var ok = dialog.getDescendantOfName('ok');

        if(strTitle == null) {
            strTitle = ux.megatron.Main.getServer().getDynamicProperty("@addin@AlertDialog Default Title");
        }
        dialog.getDescendantOfName('title').setText(strTitle);
        if(strMessage == null) {
            strMessage = ux.megatron.Main.getServer().getDynamicProperty("@addin@AlertDialog Default Alert Text");
        }
        dialog.getDescendantOfName('message').setText(strMessage);

        if(strOk === false)
            dialog.hideButton();
        else {
            if(strOk == null) {
                strOk = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn OK");
            }
            ok.setText(strOk);
        }

        if(fctOnOk != null) {
            var onExecute = "_onExecute";
            ok._onExecute = fctOnOk;
            ok.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }

        this.configureAlert(dialog, objParams);
        ux.megatron.Main.getServer().getBodyBlock().paintChild(dialog);
        dialog.focus();
        return dialog;
    }

    /**
     * Show a confirm dialog.  The signature and usage is identical to that in the standard GI confirm function, but it gives
     * a confirm dialog that uses the MatrixAdmin Visual Style.
     *
     * @param strTitle {String} the title of the dialog
     * @param strMessage {String} the message to display
     * @param fctOnOk {Function} callback function on pressing ok button, receives the dialog as an argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param fctOnCancel {Function} callback function on pressing cancel button, receives the dialog as an argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param strOk {String} the text of the ok button
     * @param strCancel {String} the text of the cancel button
     * @param intBtnDefault {int} the bold button that receives return key, 1:ok, 2:cancel, 3:no
     * @param fctOnNo {Function} callback function on pressing no button, receives the dialog as an argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param strNo {String} the text of the no button
     * @param objParams {objParams} argument to configureAlert()
     */
    main.confirm = function(strTitle, strMessage, fctOnOk, fctOnCancel, strOk, strCancel, intBtnDefault,
                                        fctOnNo, strNo, objParams) {
        var dialog = ux.megatron.Main.getServer().getBodyBlock().loadAndCache('jsxaddin://user!Megatron/components/confirmDialog.xml', false);
        var ok = dialog.getDescendantOfName('ok');
        var cancel = dialog.getDescendantOfName('cancel');
        var no = dialog.getDescendantOfName('no');
        var buttons = [ok, cancel, no];
        intBtnDefault = intBtnDefault != null ? intBtnDefault - 1 : 1;

        if(strTitle == null) {
            strTitle = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Title");
        }
        dialog.getDescendantOfName('title').setText(strTitle);
        if(strMessage == null) {
            strMessage = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Alert Text");
        }
        dialog.getDescendantOfName('message').setText(strMessage);
        if(strOk == null) {
            strOk = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn OK");
        }
        ok.setText(strOk);
        if(strCancel == null) {
            strCancel = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn Cancel");
        }
        cancel.setText(strCancel);
        if(fctOnCancel != null) {
            var onExecute = "_onExecute";
            cancel._onExecute = fctOnCancel;
            cancel.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }
        if(fctOnOk != null) {
            var onExecute = "_onExecute";
            ok._onExecute = fctOnOk;
            ok.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }
        if(fctOnNo != null || strNo != null || intBtnDefault == 3) {
            if(strNo == null) {
                strNo = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn No");
            }
            no.setText(strNo);
            if(fctOnNo) {
                var onExecute = "_onExecute";
                no._onExecute = fctOnNo;
                no.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
            }
            no.setDisplay(jsx3.gui.Block.DISPLAYBLOCK);
        }

        var defaultBtn = buttons[intBtnDefault];
        if(defaultBtn) {
            defaultBtn.setFontWeight(ux.megatron.Main.getServer().getDynamicProperty('@addin@Btn Font Weight'));

            dialog.registerHotKey(function(objEvent) {
                if(objEvent.enterKey()) {
                    this.getDescendantOfName(defaultBtn.getName()).doExecute(objEvent);
                    objEvent.cancelBubble();
                }
            }, jsx3.gui.Event.KEY_ENTER, false, false, false);
        }

        this.configureAlert(dialog, objParams);
        ux.megatron.Main.getServer().getBodyBlock().paintChild(dialog);
        dialog.focus();
        return dialog;
    }

		main.confirmUponParent = function(parent, strTitle, strMessage, fctOnOk, fctOnCancel, strOk, strCancel, intBtnDefault,
                                        fctOnNo, strNo, objParams) {
        var dialog = parent.loadAndCache('jsxaddin://user!Megatron/components/confirmDialog.xml', false);
        var ok = dialog.getDescendantOfName('ok');
        var cancel = dialog.getDescendantOfName('cancel');
        var no = dialog.getDescendantOfName('no');
        var buttons = [ok, cancel, no];
        intBtnDefault = intBtnDefault != null ? intBtnDefault - 1 : 1;

        if(strTitle == null) {
            strTitle = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Title");
        }
        dialog.getDescendantOfName('title').setText(strTitle);
        if(strMessage == null) {
            strMessage = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Alert Text");
        }
        dialog.getDescendantOfName('message').setText(strMessage);
        if(strOk == null) {
            strOk = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn OK");
        }
        ok.setText(strOk);
        if(strCancel == null) {
            strCancel = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn Cancel");
        }
        cancel.setText(strCancel);
        if(fctOnCancel != null) {
            var onExecute = "_onExecute";
            cancel._onExecute = fctOnCancel;
            cancel.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }
        if(fctOnOk != null) {
            var onExecute = "_onExecute";
            ok._onExecute = fctOnOk;
            ok.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }
        if(fctOnNo != null || strNo != null || intBtnDefault == 3) {
            if(strNo == null) {
                strNo = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn No");
            }
            no.setText(strNo);
            if(fctOnNo) {
                var onExecute = "_onExecute";
                no._onExecute = fctOnNo;
                no.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
            }
            no.setDisplay(jsx3.gui.Block.DISPLAYBLOCK);
        }

        var defaultBtn = buttons[intBtnDefault];
        if(defaultBtn) {
            defaultBtn.setFontWeight(ux.megatron.Main.getServer().getDynamicProperty('@addin@Btn Font Weight'));

            dialog.registerHotKey(function(objEvent) {
                if(objEvent.enterKey()) {
                    this.getDescendantOfName(defaultBtn.getName()).doExecute(objEvent);
                    objEvent.cancelBubble();
                }
            }, jsx3.gui.Event.KEY_ENTER, false, false, false);
        }

        this.configureAlert(dialog, objParams);
        parent.paintChild(dialog);
        dialog.focus();
        return dialog;
    }

    /**
     * Show a textbox input prompt dialog.  The signature and usage is identical to that in the standard GI prompt function, but it gives
     * a textbox input prompt dialog that uses the MatrixAdmin Visual Style.
     *
     * @param strTitle {String} the title of the dialog
     * @param strMessage {String} the message to display
     * @param fctOnOk {Function} callback function on pressing ok button, receives the dialog as an argument, and the value of the text input as a second argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param fctOnCancel {Function} callback function on pressing cancel button, receives the dialog as an argument; if null the dialog will close itself; if defined must explicitly close the dialog
     * @param strOk {String} the text of the ok button
     * @param strCancel {String} the text of the cancel button
     * @param objParams {objParams} argument to configureAlert()
     */
    main.prompt = function(strTitle, strMessage, fctOnOk, fctOnCancel, strOk, strCancel, objParams) {
        var dialog = ux.megatron.Main.getServer().getBodyBlock().loadAndCache('jsxaddin://user!Megatron/components/promptDialog.xml', false);
        var ok = dialog.getDescendantOfName('ok');
        var cancel = dialog.getDescendantOfName('cancel');

        if(strTitle == null) {
            strTitle = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Title");
        }
        dialog.getDescendantOfName('title').setText(strTitle);
        if(strMessage == null) {
            strMessage = ux.megatron.Main.getServer().getDynamicProperty("@addin@ConfirmDialog Default Alert Text");
        }
        dialog.getDescendantOfName('message').setText(strMessage);
        if(strOk == null) {
            strOk = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn OK");
        }
        ok.setText(strOk);
        if(strCancel == null) {
            strCancel = ux.megatron.Main.getServer().getDynamicProperty("@addin@Btn Cancel");
        }
        cancel.setText(strCancel);
        if(fctOnOk != null) {
            var onExecute = "_onExecute";
            ok._onExecute = fctOnOk;
            ok.setEvent("var d = this.getAncestorOfType(jsx3.gui.Dialog); this." + onExecute + "(d, d.getDescendantOfName('value').getValue());", jsx3.gui.Interactive.EXECUTE);
        }
        if(fctOnCancel != null) {
            var onExecute = "_onExecute";
            cancel._onExecute = fctOnCancel;
            cancel.setEvent("this." + onExecute + "(this.getAncestorOfType(jsx3.gui.Dialog));", jsx3.gui.Interactive.EXECUTE);
        }

        this.configureAlert(dialog, objParams);
        ux.megatron.Main.getServer().getBodyBlock().paintChild(dialog);
        jsx3.sleep(function() {
            dialog.getDescendantOfName('value').focus();
        });
        return dialog;
    };

    /**
    * Internal function used to configure an alert dialog.
    *
    * @param objDialog {jsx3.gui.Dialog} the dialog to be configured.
    * @param objParams {Object} an object containing any of the following (optional) fields:
    *        <ul><li><code>width</code> - the width to set for the dialog</li>
    *        <li><code>height</code> - the height to set for the dialog</li>
    *        <li><code>noTitle</code> - if exists, hides the dialog's title bar (be sure to include a close button!</li>
    *        <li><code>nonModal</code> - if exists, makes sure the dialog is not modal</li></ul>

    * @private
    */
    main.configureAlert = function(objDialog, objParams) {
        if(objParams == null) return;

        if(objParams.width)
            objDialog.setWidth(objParams.width, false);
        if(objParams.height)
            objDialog.setHeight(objParams.height, false);

        if(objParams.noTitle)
            objDialog.removeChild(objDialog.getChild('title'));

        if(objParams.nonModal)
            objDialog.setModal(jsx3.gui.Dialog.NONMODAL);
    };

    /**
    * Given a CDF cache document and record id, shows an error dialog by simply providing the attributes of that row to use
    * as the summary and details of the dialog.
    *
    * @param cacheId {String} the id of the CDF document in the cache
    * @param jsxid {String} the jsxid of the record to be used in the document identified by <code>cacheId</code>
    * @param shortMessageAtt {String} the name of the attribute in the record to use as the content of the summary
    * @param longMessageAtt {String} the name of the attribute in the record to use as the content of the details
    * @param shortLabel {String} the optional label to use for the summary area
    * @param longLabel {String} the optional label to use for the details area
    * @param dialogTitle {String} the optional title for the dialog
    */
    main.showErrorDialog = function(cacheId, jsxid, shortMessageAtt, longMessageAtt, shortLabel, longLabel, dialogTitle) {
        var doc = ux.megatron.Main.getServer().getCache().getDocument(cacheId);
        if (doc) {
            var record = doc.getRecordNode ? doc.getRecordNode(jsxid) : doc.selectSingleNode("//*[@jsxid='"+jsxid+"']");
            
            if (record) {
                var shortMessage = record.getAttribute(shortMessageAtt);
                var longMessage = record.getAttribute(longMessageAtt);
                if (!shortLabel) {
                    shortLabel = ux.megatron.Main.getServer().getDynamicProperty("@ErrMsgDialog Summary Label");
                }
                if (!longLabel) {
                    longLabel = ux.megatron.Main.getServer().getDynamicProperty("@ErrMsgDialog Details Label");
                }
                if (!dialogTitle) {
                    dialogTitle = ux.megatron.Main.getServer().getDynamicProperty("@ErrMsgDialog Title");
                }
                var block = ux.megatron.Main.getServer().getJSXByName("dlgMessageDetails_30");
                if (!block) {
                    var bodyblock = ux.megatron.Main.getServer().getBodyBlock();
                    block = bodyblock.load("jsxaddin://user!Megatron/components/messageDialog.xml", true);
                }
                block.getDescendantOfName("txtMessageSummary_30").setValue(shortMessage, true);
                block.getDescendantOfName("txtbxMessageDetails_30").setValue(longMessage, true);
                block.getDescendantOfName("lblMessageSummaryLabel_30").setText(shortLabel, true);
                block.getDescendantOfName("lblMessageDetailsLabel_30").setText(longLabel, true);
                block.getDescendantOfName("windowBar").setText(dialogTitle, true);
            }
            else {
                // throw exception?
            }
        }
        else {
            // throw exception here?
        }
    }

    /**
    * Utility function to apply a mask to a given block using a custom color. The mask can be hidden again via the usual
    * means (call the <code>hideMask</code> function directly on the block).
    *
    * @param block {jsx3.gui.Block} the block to apply the mask to.
    * @param strColor {String} the string representation of the color to use for the mask.  All tthe standard javascript
    *                          string representations of colors are supported (named colors, Hex code, etc.).
    */
    main.showMask = function(block, strColor) {
        block.showMask();
        var arr = block.getChildren();
        var child = arr[arr.length - 1];
        child.setDynamicProperty("jsxbgcolor", null);
        if(!strColor) {
            strColor = "#666666";
        }
        child.setBackgroundColor(strColor, true);
    }

});